package lapsnake.model.dnd;

import java.awt.Component;
import java.awt.Point;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTargetContext;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.io.IOException;

import javax.swing.JOptionPane;

import lapsnake.model.LapNode;

public interface DNDTarget<T extends LapNode> extends DropTargetListener {
	
	DNDFlavor<T> getSupportedFlavor();
	
	@Override
	public default void dragEnter(DropTargetDragEvent dtde) {
		if (dtde.isDataFlavorSupported(getSupportedFlavor()))
			dtde.acceptDrag(DnDConstants.ACTION_MOVE);
		else 
			dtde.rejectDrag();
		
	}
	
	@Override
	public default void dragOver(DropTargetDragEvent dtde) {
	}
	
	@Override
	public default void dropActionChanged(DropTargetDragEvent dtde) {
	}
	
	@Override
	public default void dragExit(DropTargetEvent dte) {
	}
	
	@Override
	public default void drop(DropTargetDropEvent dtde) {
		
		boolean success = false;
		if (dtde.isDataFlavorSupported(getSupportedFlavor())) {
			DropTargetContext dtc = dtde.getDropTargetContext();
			Component component = dtc.getComponent();
			Transferable transferable = dtde.getTransferable();
			try {
				Object data = transferable.getTransferData(getSupportedFlavor());
				if (data instanceof LapNode && component == this) {
					LapNode node = (LapNode) data;
					//Do stuff
					nodeDropped(node, dtde.getLocation());
					success = true;
					dtde.acceptDrop(DnDConstants.ACTION_MOVE);
				}
			} catch (IllegalArgumentException | UnsupportedFlavorException | IOException exp) {
				JOptionPane.showMessageDialog(component, exp.getMessage(), "Cannot drop here...", JOptionPane.ERROR_MESSAGE);
			}
		}
		if(!success)
			dtde.rejectDrop();
		dtde.dropComplete(success);
		
	}

	public void nodeDropped(LapNode node, Point location) throws IllegalArgumentException; 
}
